#ifndef __BMPFILE_H__
#define __BMPFILE_H__

#include<stdio.h>
#include<stdlib.h>

/* BMP 对象的类型定义 */
typedef struct {
    int   width;   /* 宽度 */
    int   height;  /* 高度 */
    int   stride;  /* 行字节数 */
    int   cdepth;  /* 像素位数 */
    void* pdata;   /* 指向数据 */
} BMP;

//chong ming ming
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
//使结构体按1字节方式对齐
#pragma pack(1)
typedef struct {
	uint16_t bfType;
	uint32_t bfSize;
	uint16_t bfReserved1;
	uint16_t bfReserved2;
	uint32_t bfOffBits;
	uint32_t biSize;
	uint32_t biWidth;
	uint32_t biHeight;
	uint16_t biPlanes;
	uint16_t biBitCount;
	uint32_t biCompression;
	uint32_t biSizeImage;
	uint32_t biXPelsPerMeter;
	uint32_t biYPelsPerMeter;
	uint32_t biClrUsed;
	uint32_t biClrImportant;
}BMPFILEHEADER;
#pragma pack()

//int  bmp_load(BMP* pb, char* file);
//int  bmp_save(BMP* pb, char* file);
//void bmp_free(BMP* pb);
//void bmp_setpixel(BMP* pb, int x, int y, int r, int g, int b);
//void bmp_getpixel(BMP* pb, int x, int y, int* r, int* g, int* b);



BMPFILEHEADER header = { };
int bmp_load(BMP* pb, char* file) {

//file------x *file
	FILE *fp = fopen(file, "rb");

	if (fp)
	{
		fread(&header, 1, sizeof(header), fp);

//???? wei shen me bu neng yong "."
		pb->width = header.biWidth;
		pb->height = header.biHeight;
		pb->stride = header.biWidth * header.biBitCount / 8;
		pb->cdepth = header.biBitCount;
		pb->pdata = malloc(header.biSizeImage);

		fread(pb->pdata, 1, header.biSizeImage, fp);
		fclose(fp);

	}

	return (sizeof(header) + header.biSizeImage);
}

int bmp_save(BMP* pb, char* file)
{
	FILE *fc = fopen(file, "wb");

	if(fc)
	{
		fwrite(&header, 1 , 54 , fc);
		fwrite(pb->pdata, 1 ,(pb->width * pb->height) * pb->cdepth / 8, fc);
		fclose(fc);
	}

	return (54 + (pb->width * pb->height) * pb->cdepth/8);
}

//free()是C语言中释放内存空间的函数，通常与申请内存空间的函数malloc()结合使用，可以释放由 malloc()、calloc()、realloc() 等函数申请的内存空间
//free只是释放了malloc所申请的内存，并没有改变指针的值
//野指针（野指针指指向一个已删除的对象或未申请访问受限内存区域的指针。与空指针不同，野指针无法通过简单地判断是否为NULL避免）。为了避免错误，所以最好在free之后，使指针指向NULL。
void bmp_free(BMP* pb)
{
	free(pb->pdata);
	pb->pdata = NULL;
	pb = NULL;
}

void bmp_setpixel(BMP* pb, int x, int y, int r, int g, int b)
{
//警告：取消引用'void *'指针[默认启用]
	uint8_t *temp = pb->pdata;
//错误：一元“*”的类型参数无效（有“int”）
	int pub = 3 * x + y * pb->stride;
	temp = temp + pub;
	*(temp) = b;
	*(temp + 1) = g;
	*(temp + 2) = r;
}


void bmp_getpixel(BMP* pb, int x, int y, int* r, int* g, int* b)
{
	uint8_t *temp = pb->pdata;
	int pub = 3 * x + y * pb->stride;

	temp = temp + pub;
	*b = *temp;
	*g = *(temp + 1);
	*r = *(temp + 2);
}

#endif
